﻿

using NModbus;
using NModbus.Serial;
using System.Diagnostics;
using System;
using System.IO.Ports;
using Newtonsoft.Json.Linq;

namespace DualPlaneFR4Paster.Common.Services
{
    public class PLCModbusService : IPLCModbusService
    {
        SerialPort serialPort = new SerialPort();
        IModbusMaster master;
        private object _lock1 = new object();
        public bool[] XCoils_X0 { get; set; }
        public bool[] XCoils_X10000 { get; set; }
        public bool[] XCoils_X10100 { get; set; }
        public bool[] XCoils_X10200 { get; set; }
        public bool[] MCoils_M2000 { get; set; }

        public void Close()
        {
            try
            {
                master.Dispose();
                serialPort.Close();
                serialPort.Dispose();
            }
            catch { }
        }

        public bool Connect(string _portName)
        {
            try
            {
                if (this.serialPort.IsOpen)
                {
                    Debug.WriteLine($"PLC串口{_portName}已打开");
                    return false;
                }
                else
                {
                    this.serialPort.PortName = _portName;
                    serialPort.BaudRate = 19200;
                    serialPort.DataBits = 8;
                    serialPort.Parity = Parity.Even;
                    serialPort.StopBits = StopBits.One;
                    this.serialPort.Open();
                    this.serialPort.DiscardInBuffer();
                    this.serialPort.DiscardOutBuffer();
                    this.serialPort.WriteTimeout = 500;
                    this.serialPort.ReadTimeout = 500;
                    var factory = new ModbusFactory();
                    master = factory.CreateRtuMaster(serialPort);
                    return true;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return false;
        }

        public bool[] ReadM(byte station, ushort address, ushort count)
        {
            try
            {
                object @lock = this._lock1;
                lock (@lock)
                {
                    return master.ReadCoils(station, address, count);
                }
            }
            catch
            {
                return null;
            }
        }

        public void SetM(byte station, ushort address, bool value)
        {
            try
            {
                object @lock = this._lock1;
                lock (@lock)
                {
                    master.WriteSingleCoil(station, address, value);
                }
            }
            catch { }
        }
        public int ReadDHD(byte station, int address)
        {
            try
            {
                object @lock = this._lock1;
                lock (@lock)
                {
                    ushort[] values = master.ReadHoldingRegisters(station, (ushort)(address + 0xA080), 2);
                    var valuesStr = values[1].ToString("X4") + values[0].ToString("X4");
                    return Convert.ToInt32(valuesStr, 16);
                }
            }
            catch { return 0; }
        }
        public void WriteDHD(byte station, int address,int value)
        {
            try
            {
                object @lock = this._lock1;
                lock (@lock)
                {
                    string valueStr = value.ToString("X8");
                    ushort[] values = new ushort[2] {
                        Convert.ToUInt16(valueStr.Substring(4,4),16),Convert.ToUInt16(valueStr.Substring(0,4),16)
                    };
                    master.WriteMultipleRegisters(station, (ushort)(address + 0xA080), values);
                }
            }
            catch { }
        }
        public PLCModbusService()
        {
            XCoils_X0 = new bool[36];
            XCoils_X10000 = new bool[16];
            XCoils_X10100 = new bool[16];
            XCoils_X10200 = new bool[16];
            MCoils_M2000 = new bool[64];
        }
    }
}
